< previous page page_170 next page >

Page 170
Solution 7
Supercharged Graphics
Like most API-related problems, the declaration is the culprit. Let's take a close look at the SDK description of the Polyline function:
BOOL Polyline(
    HDC hdc,     // handle of device context
    CONST POINT *lppt,   // address of array containing endpoints
    int cPoints  // number of points in the array
   );

Private Declare Function Polyline Lib "gdi32" (ByVal hdc As Long, _
lppt() As POINTAPI, ByVal nCount As Long) As Long
This is a function that returns a BOOL. A Win32 BOOL is a Long value, so that much is correct. The DLL is gdi32, which is also correct, since gdi32 is the DLL that holds all of the core graphics library functions.
The count is an integer, and Win32 integers are 32 bits, so the nCount parameter is also correct.
0170-01.gif
Figure S7-1:
The lppt parameter as seen by the Polyline function
What about lpPoints?
Figure S7-1 shows the lppt parameter as seen by the Polyline function. The function expects to see as a parameter a pointer to the first POINTAPI structure in an array of structures in memory.
The Visual Basic declaration defines this parameter as lppt() As POINTAPI. What is passed to an API function when you declare an array in this manner? The answer is shown in Figure S7-2.
Figure S7-2 shows that there is a lot more than meets the eye when it comes to array declarations. Visual Basic stores arrays internally using the OLE array storage mechanism. The OLE array storage system uses a structure called a SAFEARRAY to manage arrays. Each array has a SAFEARRAY structure that contains all of the information necessary to describe the array to the system. The OLE API contains a number of functions that create and manipulate SAFEARRAY structures. When you declare a variable as an array in Visual Basic, the variable actually contains a pointer to a SAFEARRAY

 
< previous page page_170 next page >